﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;

using HWND = System.IntPtr;

namespace Loong.Console
{
 /// <summary>
 /// UserControl1 的摘要说明。
 /// </summary>
 public class SyntaxEditor:RichTextBox
 {
  /// <summary>
  /// 必需的设计器变量。
  /// </summary>
  private System.ComponentModel.Container components = null;

//使用win32api：SendMessage来防止控件着色时的闪烁现象

  [DllImport("user32")] private static extern int SendMessage(HWND hwnd, int wMsg, int wParam, IntPtr lParam);
  private const int WM_SETREDRAW = 0xB;

  public SyntaxEditor()
  {
   // 该调用是 Windows.Forms 窗体设计器所必需的。
   InitializeComponent();
   base.WordWrap=false;
   // TOD 在 InitComponent 调用后添加任何初始化

  }

  /// <summary>
  /// 清理所有正在使用的资源。
  /// </summary>
  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
    if( components != null )
     components.Dispose();
   }
   base.Dispose( disposing );
  }

  #region 组件设计器生成的代码
  /// <summary>
  /// 设计器支持所需的方法 - 不要使用代码编辑器
  /// 修改此方法的内容。
  /// </summary>
  private void InitializeComponent()
  {
   //
   // SyntaxEditor
   //
   this.Name = "SyntaxEditor";

  }
  #endregion

 //重写基类的OnTextChanged方法。为了提高效率，程序是对当前文本插入点所在行进行扫描，

//以空格为分割符，判断每个单词是否为关键字，并进行着色。

  protected override void OnTextChanged(EventArgs e)   
  {
   if(base.Text!="")
   {
    int selectStart=base.SelectionStart;
    int line=base.GetLineFromCharIndex(selectStart);

    string lineStr=base.Lines[line];
    int linestart=0;
    for(int i=0;i<line;i++)
    {
     linestart+=base.Lines[i].Length+1;
    }
    
    SendMessage(base.Handle, WM_SETREDRAW, 0, IntPtr.Zero);

    base.SelectionStart=linestart;
    base.SelectionLength=lineStr.Length;
    base.SelectionColor=Color.Black;
    base.SelectionStart=selectStart;
    base.SelectionLength=0;

    string[] words=lineStr.Split(new char[]{' ','}','{','(',')'});
    Parser parser=new Parser(this.language);
    for(int i=0;i<words.Length;i++)
    {
     if(parser.IsKeyWord(words[i]))
     { 
      
      int length=0;
      for(int j=0;j<i;j++)
      {
       length+=words[j].Length;      
      }
      length+=i;

      int index=lineStr.IndexOf(words[i],length);
      
      

      base.SelectionStart=linestart+index;
      base.SelectionLength=words[i].Length;
      base.SelectionColor = color;
      if (isBold)
      {
          base.SelectionFont = new Font(Font, FontStyle.Bold);
      }
      base.SelectionStart=selectStart;
      base.SelectionLength=0;
      base.SelectionColor=Color.Black;

     }
    }
    SendMessage(base.Handle, WM_SETREDRAW, 1, IntPtr.Zero);
    base.Refresh();
   }
   base.OnTextChanged (e);
  }

  public new bool WordWrap
  {
   get{return base.WordWrap;}
  }

  private Languages language=Languages.CSHARP;

  public Languages Language
  {
   get{return this.language;}
   set{this.language=value;}
  }

  private Color color = Color.Blue;

  public Color SelectColor
  {
      get { return this.color; }
      set { this.color = value; }
  }

  private bool isBold=false;

  public bool IsBold
  {
      get { return this.isBold; }
      set { this.isBold = value; }
  }

 }
}